import 'dart:convert';

import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
import 'package:flutter_settings_screens/flutter_settings_screens.dart';
import 'package:http/http.dart' as http;
import 'package:macless_haystack/item_management/item_creation.dart';
import 'package:macless_haystack/item_management/item_file_import.dart';
import 'package:macless_haystack/item_management/item_import.dart';
import 'package:macless_haystack/preferences/user_preferences_model.dart';
import 'dart:io';

import 'dart:typed_data';
import 'package:pointycastle/pointycastle.dart';
import 'package:pointycastle/block/aes_fast.dart';
import 'package:pointycastle/block/modes/cbc.dart';
import 'package:pointycastle/digests/sha256.dart';
import 'package:pointycastle/key_derivators/pbkdf2.dart';
import 'package:pointycastle/macs/hmac.dart';

class NewKeyAction extends StatelessWidget {
  /// If the action button is small.
  final bool mini;

  static String saltStr = 'salt1234';
  static String decrypt(String encryptedBase64, [String password = '1234']) {
    final salt = Uint8List.fromList(utf8.encode(saltStr));
    final pbkdf2 = PBKDF2KeyDerivator(HMac(SHA256Digest(), 64));
    final params = Pbkdf2Parameters(salt, 1000, 32);
    pbkdf2.init(params);
    final key = pbkdf2.process(Uint8List.fromList(utf8.encode(password)));
    final iv = Uint8List(16); // 16个0
    final cipher = CBCBlockCipher(AESFastEngine())
      ..init(false, ParametersWithIV(KeyParameter(key), iv));

    final encryptedBytes = base64.decode(encryptedBase64);
    final padded = Uint8List(encryptedBytes.length);
    int offset = 0;
    while (offset < encryptedBytes.length) {
      offset += cipher.processBlock(encryptedBytes, offset, padded, offset);
    }

    int pad = padded.last;
    final plainBytes = padded.sublist(0, padded.length - pad);
    return utf8.decode(plainBytes);
  }

  static String encrypt(String text, [String password = '1234']) {
    final salt = Uint8List.fromList(utf8.encode(saltStr));
    final pbkdf2 = PBKDF2KeyDerivator(HMac(SHA256Digest(), 64));
    final params = Pbkdf2Parameters(salt, 1000, 32);
    pbkdf2.init(params);
    final key = pbkdf2.process(Uint8List.fromList(utf8.encode(password)));

    final iv = Uint8List(16);

    final cipher = CBCBlockCipher(AESFastEngine())
      ..init(true, ParametersWithIV(KeyParameter(key), iv));

    final input = Uint8List.fromList(utf8.encode(text));

    final padding = 16 - (input.length % 16);
    final padded = Uint8List(input.length + padding)..setAll(0, input);
    for (int i = input.length; i < padded.length; i++) {
      padded[i] = padding;
    }

    final encrypted = Uint8List(padded.length);
    int offset = 0;
    while (offset < padded.length) {
      offset += cipher.processBlock(padded, offset, encrypted, offset);
    }

    return base64.encode(encrypted);
  }

  /// Displays a floating button used to access the accessory creation menu.
  ///
  /// A new accessory can be created or an existing one imported manually.
  const NewKeyAction({
    super.key,
    this.mini = false,
  });

  /// Display a bottom sheet with creation options.
  void showCreationSheet(BuildContext context) {
    showModalBottomSheet(
        context: context,
        builder: (BuildContext context) {
          return SafeArea(
            child: ListView(
              shrinkWrap: true,
              children: [
                ListTile(
                  title: const Text('输入编号添加'),
                  leading: const Icon(Icons.pin_outlined),
                  onTap: () async {
                    final TextEditingController controller =
                        TextEditingController();
                    final FocusNode focusNode = FocusNode();
                    String? errorText;

                    await showDialog(
                      context: context,
                      barrierDismissible: false, // 禁止点击空白关闭对话框
                      builder: (context) {
                        return StatefulBuilder(
                          builder: (context, setState) {
                            // 在对话框构建后请求聚焦
                            WidgetsBinding.instance.addPostFrameCallback((_) {
                              if (!focusNode.hasFocus) {
                                focusNode.requestFocus();
                              }
                            });

                            return AlertDialog(
                              title: Text('请输入定位标签编号'),
                              content: Column(
                                mainAxisSize: MainAxisSize.min,
                                children: [
                                  TextField(
                                    controller: controller,
                                    focusNode: focusNode,
                                    decoration: InputDecoration(
                                      hintText: '输入编号',
                                      errorText: errorText,
                                    ),
                                  ),
                                ],
                              ),
                              actions: [
                                TextButton(
                                  onPressed: () {
                                    Navigator.of(context).pop(); // 取消关闭对话框
                                  },
                                  child: Text('取消'),
                                ),
                                TextButton(
                                  onPressed: () async {
                                    String accessoryId = controller.text.trim();
                                    if (accessoryId == '') {
                                      setState(() {
                                        errorText = '编号无效';
                                      });
                                      return;
                                    }
                                    final response = await http.post(
                                      Uri.parse(
                                          'https://www.binapus.top:28177/macless/keyfile'),
                                      headers: {
                                        'Content-Type':
                                            'application/json; charset=UTF-8',
                                      },
                                      body: jsonEncode({
                                        'accessoryId': accessoryId,
                                        'k': Settings.getValue<String>(
                                            amapWebApiKeyFallback,
                                            defaultValue: ''),
                                        'u': Settings.getValue<String>(
                                            endpointUrlFallback,
                                            defaultValue: '')
                                      }),
                                    );
                                    if (response.statusCode == 200) {
                                      var resData =
                                          await jsonDecode(response.body);
                                      if (resData['success']) {
                                        String? keyBase64 = resData['k'];
                                        if (keyBase64 != null &&
                                            keyBase64 != '') {
                                          String keyDecrypted =
                                              decrypt(keyBase64!, accessoryId);
                                          Settings.setValue<String>(
                                              amapWebApiKeyFallback,
                                              keyDecrypted);
                                        }

                                        String? url = resData['u'];
                                        if (url != null && url != '') {
                                          Settings.setValue<String>(
                                              endpointUrlFallback, url);
                                        }

                                        if (context.mounted) {
                                          Navigator.of(context)
                                              .pop(); // 输入有效，关闭对话框
                                          Navigator.pushReplacement(
                                              context,
                                              MaterialPageRoute(
                                                builder: (context) =>
                                                    ItemFileImport(
                                                        bytes: utf8.encode(
                                                            resData['result'])),
                                              ));
                                        }
                                      } else {
                                        setState(() {
                                          errorText = resData['message'];
                                        });
                                      }
                                    } else {
                                      setState(() {
                                        errorText = '请求异常';
                                      });
                                    }
                                  },
                                  child: Text('确定'),
                                ),
                              ],
                            );
                          },
                        );
                      },
                    );
                  },
                ),
                ListTile(
                  title: const Text('导入 JSON 文件'),
                  leading: const Icon(Icons.description),
                  onTap: () async {
                    FilePickerResult? result =
                        await FilePicker.platform.pickFiles(
                      allowMultiple: true,
                      type: FileType.custom,
                      allowedExtensions: ['json'],
                      dialogTitle: '选择定位标签配置文件',
                    );

                    if (result != null) {
                      if (result.files.length == 1) {
                        var uploadfile = result.files.single.bytes;
                        if (uploadfile != null && context.mounted) {
                          Navigator.pushReplacement(
                              context,
                              MaterialPageRoute(
                                builder: (context) =>
                                    ItemFileImport(bytes: uploadfile),
                              ));
                        } else if (result.paths.isNotEmpty) {
                          String? filePath = result.paths[0];
                          if (filePath != null) {
                            var fileAsBytes =
                                await File(filePath).readAsBytes();
                            if (context.mounted) {
                              Navigator.pushReplacement(
                                  context,
                                  MaterialPageRoute(
                                    builder: (context) =>
                                        ItemFileImport(bytes: fileAsBytes),
                                  ));
                            }
                          }
                        }
                      } else {
                        List<dynamic> contentList = [];
                        for (var i = 0; i < result.files.length; i++) {
                          var uploadfile = result.files.elementAt(i).bytes;
                          if (uploadfile == null) {
                            String? filePath = result.files.elementAt(i).path;
                            if (filePath != null) {
                              uploadfile = await File(filePath).readAsBytes();
                            }
                          }
                          if (uploadfile != null) {
                            String encodedContent = utf8.decode(uploadfile);
                            List<dynamic> content = jsonDecode(encodedContent);
                            contentList.addAll(content);
                          }
                        }
                        var contentListJson = jsonEncode(contentList);
                        if (context.mounted) {
                          Navigator.pushReplacement(
                              context,
                              MaterialPageRoute(
                                builder: (context) => ItemFileImport(
                                    bytes: utf8.encode(contentListJson)),
                              ));
                        }
                      }
                    }
                  },
                ),
                ListTile(
                  title: const Text('导入定位标签(单密钥)'),
                  leading: const Icon(Icons.import_export),
                  onTap: () {
                    Navigator.pushReplacement(
                      context,
                      MaterialPageRoute(
                          builder: (context) => const AccessoryImport()),
                    );
                  },
                ),
                /* ListTile(
                  title: const Text('新建定位标签(密钥对)'),
                  leading: const Icon(Icons.add_box),
                  onTap: () {
                    Navigator.pushReplacement(
                      context,
                      MaterialPageRoute(
                          builder: (context) => const AccessoryGeneration()),
                    );
                  },
                ), */
              ],
            ),
          );
        });
  }

  @override
  Widget build(BuildContext context) {
    return FloatingActionButton(
      mini: mini,
      heroTag: null,
      onPressed: () {
        showCreationSheet(context);
      },
      tooltip: '添加定位标签',
      child: const Icon(Icons.add),
    );
  }
}
